#include <fcntl.h>
#include <semaphore.h>
#include <unistd.h>

#include <cstdlib>
#include <cstring>
#include <iostream>

using namespace std;

// USE FOR POSIX SEMAPHORES

static int cur = 0;

void *producer(void *) {
  sem_t *sem = nullptr;
  // 打开有名信号量
  // 参数：信号量名，创建模式，创建的权限，信号量初始值
  sem = sem_open("NAME", O_CREAT, O_RDWR | 0666, 0);
  if (sem == SEM_FAILED) {
    cerr << "sem_open failed" << endl;
    return nullptr;
  }
  while (cur < 5) {
    // P操作
    while (sem_post(sem)) {
      cerr << "sem_post failed" << endl;
      sleep(1);
    }
    cur++;
    cout << "Producing Finish" << endl;
    fflush(stdout);
    sleep(1);
  }
  // 关闭有名信号量
  sem_close(sem);
  // 销毁有名信号量
  sem_unlink("NAME");
  return NULL;
}

void *cusumer(void *) {
  sem_t *sem = nullptr;
  // 打开有名信号量
  // 参数：信号量名，创建模式，创建的权限，信号量初始值
  sem = sem_open("NAME", O_CREAT, O_RDWR | 0666, 0);
  if (sem == SEM_FAILED) {
    cerr << "sem_open failed" << endl;
    return nullptr;
  }
  while (1) {
    // P操作
    if (sem_wait(sem)) {
      cerr << "sem_wait failed" << endl;
      sleep(1);
      continue;
    }
    cur--;
    cout << "Consuming Finish" << endl;
    fflush(stdout);
    sleep(1);
  }
  // 关闭有名信号量
  sem_close(sem);
  return NULL;
}

int main(int argc, char const *argv[]) {
  pthread_t p_producer, p_cusumer;
  pthread_create(&p_producer, NULL, producer, NULL);
  pthread_create(&p_cusumer, NULL, cusumer, NULL);
  pthread_join(p_producer, NULL);
  pthread_join(p_cusumer, NULL);
  return 0;
}
